﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Satates;
using Operators;

namespace Algorithms
{
    public class Algorithm
    {
        protected Stack<State> btStack;
        protected List<iOperator> operators;
        protected State initialState;
        protected List<State> finalStates;
        protected int operatorNumber = 0;
        protected List<string> log;

        protected bool found(State thisState)
        {
            foreach (var st in btStack)
            {
                if (thisState.equals(st)) return true;
            }
            return false;
            /*for(StackIterator<State<Template>> it=new StackIterator<State<Template>>(btStack); it.hasNext();)
            {
                if(thisState.equals(it.next())) return true;
            }
            return false;*/
        }


        public Algorithm(State iState, List<State> fStates, List<iOperator> opr, List<string> _Log)
        {
            btStack = new Stack<State>();
            initialState = iState;
            finalStates= new List<State>();
            finalStates.AddRange(fStates.ToArray());
            operators = opr;
            operatorNumber = operators.Count() - 1;
            log = _Log;
        }


        protected bool solutionFound(State thisState)
        {
            for (int i = 0; i < finalStates.Count(); i++)
            {
                if (thisState.equals((State)finalStates[i]))
                {
                    return true;
                }
            }
            return false;
        }

        protected int getIndex(iOperator op)
        {
            for (int i = 0; i < operators.Count(); i++)
            {

                if (operators[i].getOperatorNumber() == op.getOperatorNumber()) {
                    return i; }
            }
            return 0;

        }

        protected void print(State thisState)
        {
                log.Add("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
            if (thisState.CurrentOperator != null)
                log.Add(thisState.CurrentOperator.ToString());
            log.Add("\n");
            log.Add(thisState.CurrentState.ToString());
            log.Add("\n");
        }
        protected void closeLog()
        {
            log.Add("Solution found using Search... ");

        }
        public List<string> Log
        {
            get { return log; }
        }

        public void executeAlgorithm()
	{
		init();
		btStack.Push(initialState);
		if(solveProblem()==true){
            foreach(var st in btStack)
        {
            print(st);
        }
		   /* for(StackIterator<State<Template>> it=new StackIterator<State<Template>>(btStack); it.hasNext();)
		    {
			    print(it.next());
		    }*/
		}
		else
        {
            log.Add("Error");
            log.Add("No Solution found using Search... ");
		}
	}
        public virtual  bool solveProblem()
        {
            return false;
        }
        public virtual  void init(){return;}
    }
}
